package com.zjm;

import java.io.*;
import java.util.Arrays;
import java.util.Objects;

/**
 * 通过java的序列化和反序列化机制实现 数组的 deep copy
 */
public class DeepCopy {

    public static void main(String[] args) throws InterruptedException, IOException, ClassNotFoundException {

        A[] list = new A[3];
        A a = new A(1);
        A b = new A(2);
        A c = new A(3);
        list[0] = a;
        list[1] = b;
        list[2] = c;

        A[] clone = deepClone(list);

        System.out.println("list : " + Arrays.toString(list));
        System.out.println("clone: " + Arrays.toString(clone));

        for (A e : list) {
            e.setVersion(e.getValue());
        }

        System.out.println();

        System.out.println("list : " + Arrays.toString(list));
        System.out.println("clone: " + Arrays.toString(clone));
    }

    private static A[] deepClone(A[] list) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(list);
        ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(byteOut.toByteArray()));
        A[] o = (A[]) in.readObject();
        return o;
    }
}

class A implements Cloneable, Serializable{

    @Override
    public A clone() throws CloneNotSupportedException {
        super.clone();
        A a = (A) super.clone();
        A result = new A(a.getVersion());
        result.setVersion(result.version);
        return result;
        //return super.clone();
    }

    private int version;

    public A(int value) {
        this.value = value;
        this.version = 0;
    }

    private int value;

    @Override
    public String toString() {
        return "A{" + value + ":" + version  + "}";
    }

    public int getValue() {
        return value;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public void setValue(int value) {
        this.value = value;
    }

}
